#include "engine.h"
#include "qdebug.h"
#include "QException"
#include <iostream>
using namespace std;
void Engine::find_queen_pos(int c, int player,queue<int> &futurechess, int *res, int dis,int &blackoccupy,int &whiteoccupy){
    if(player == blackc){
        for (int i = 0;i < 8;i++ ) {
            int chess = c + dection[i];
            while(res[chess] != UNTOUCH){
                if (res[chess] == 0){
                    futurechess.push(chess);
                    res[chess] = dis;
                    blackoccupy++;
                }
                chess += dection[i];
            }
        }
    }
    else{
        for (int i = 0;i < 8;i++ ) {
            int chess = c + dection[i];
            while( res[chess] != UNTOUCH){
                if(res[chess] == 0){
                    futurechess.push(chess);
                    res[chess] = dis;
                    whiteoccupy++;
                }
                else if(res[chess] == abs(dis)){
                    futurechess.push(chess);
                    res[chess] = dis;
                    blackoccupy--;
                }
                chess += dection[i];
            }
        }
    }
}

char Engine::queen_move(const Cb_with_num &cb){
    int res[144];
    //复制好的棋盘中，空格为0，其余全为不可达
    //res在之后的广度优先中，白子到达为正数，黑子到达为负数，两种棋子距离相等设为不可达
    for (int i = 0;i < 144;i++ ) {
        if(cb.chessborad[i] == 2) res[i] = 0;
        else res[i] = UNTOUCH;
    }
    queue<int> queue;
    //id是为区分当前应该为队列加入黑方子节点还是白方子节点的变量，
    //id为奇数是白方，id为偶数是黑方
    int blackDis = 0;
    int whiteDis = 0;
    int first_size = 4;
    int size = 0,i = 0;
    int blackOccupy = 0,whiteOccupy = 0;
    for (int i = 0; i< 4 ;i++) queue.push(cb.movechess.blackchess[i].i);
    for (int i = 0; i< 4 ;i++) queue.push(cb.movechess.whitechess[i].i);

    while(!queue.empty()){
        size = queue.size();
        blackDis++;
        i = 0;
        for (;i < first_size;i++ ) {
            int n = queue.front();
            find_queen_pos(n,blackc,queue,res,blackDis,blackOccupy,whiteOccupy);
            queue.pop();
        }
        first_size = queue.size() + first_size - size;

        whiteDis--;
        for (;i < size;i++ ) {
            int n = queue.front();
            find_queen_pos(n,whitec,queue,res,whiteDis,blackOccupy,whiteOccupy);
            queue.pop();
        }
    }
    if(*player == blackc) return blackOccupy - whiteOccupy;
    else return whiteOccupy - blackOccupy;
}

void Engine::find_king_pos(int c, int player,queue<int> &futurechess, int *res,int dis,int &blackoccupy,int &whiteoccupy){
    if(player == blackc){
        for (int i = 0;i < 8;i++ ) {
            int chess = c + dection[i];
            if (res[chess] == 0){
                futurechess.push(chess);
                res[chess] = dis;
                blackoccupy++;
            }
        }
    }
    else{
        for (int i = 0;i < 8;i++ ) {
            int chess = c + dection[i];
            if(res[chess] == 0){
                futurechess.push(chess);
                res[chess] = dis;
                whiteoccupy++;
            }
            else if(res[chess] == abs(dis)) {
                blackoccupy--;
                futurechess.push(chess);
                res[chess] = dis;
            }
        }
    }
}

char Engine::king_move(const Cb_with_num &cb){
    int res[144];
    //复制好的棋盘中，空格为0，其余全为不可达
    //res在之后的广度优先中，白子到达为正数，黑子到达为负数，两种棋子距离相等设为不可达
    for (int i = 0;i < 144;i++ ) {
        if(cb.chessborad[i] == 2) res[i] = 0;
        else res[i] = UNTOUCH;
    }
    queue<int> queue;
    //id是为区分当前应该为队列加入黑方子节点还是白方子节点的变量，
    //id为奇数是白方，id为偶数是黑方
    int blackDis = 0;
    int whiteDis = 0;
    int first_size = 4;
    int size = 0,i = 0;
    int blackOccupy = 0,whiteOccupy = 0;
    for (int i = 0; i< 4 ;i++) queue.push(cb.movechess.blackchess[i].i);
    for (int i = 0; i< 4 ;i++) queue.push(cb.movechess.whitechess[i].i);

    while(!queue.empty()){
        size = queue.size();
        blackDis++;
        i = 0;
        for (;i < first_size;i++ ) {
            int n = queue.front();
            find_king_pos(n,blackc,queue,res,blackDis,blackOccupy,whiteOccupy);
            queue.pop();
        }
        first_size = queue.size() + first_size - size;

        whiteDis--;
        for (;i < size;i++ ) {
            int n = queue.front();
            find_king_pos(n,whitec,queue,res,whiteDis,blackOccupy,whiteOccupy);
            queue.pop();
        }
    }
    if(*player == blackc) return blackOccupy - whiteOccupy;
    else return whiteOccupy - blackOccupy;
}



